home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / samba.idb / usr / samba / bin / sambalp.z / sambalp
Encoding:
Text File  |  1998-10-28  |  4.2 KB  |  151 lines

  1. #!/bin/perl
  2. #
  3. # Hacked by Alan Stebbens <aks@sgi.com> to setuid to the username if 
  4. # valid on this system.  Written as a secure Perl script.  To enable,
  5. #
  6. #    chown root /usr/samba/bin/sambalp
  7. #    chmod u+s,+x /usr/samba/bin/sambalp
  8. #
  9. # If setuidshells is not enabled on your system, you must also do this:
  10. #
  11. #    systune -i
  12. #    nosuidshells = 0
  13. #    y
  14. #    quit
  15. #
  16. #    reboot
  17. #
  18. # This script will still work as a normal user; it will not try
  19. # to setuid in this case.
  20. #
  21. # If the "$PSFIX" variable is set below...
  22. #
  23. # Workaround Win95 printer driver/Impressario bug by removing
  24. # the PS check for available virtual memory.  Note that this
  25. # bug appears to be in all Win95 print drivers that generate
  26. # PostScript; but is for certain there with a QMS-PS 810 (the
  27. # printer type I configure on the Win95-side for printing with
  28. # Samba).
  29. #
  30. # the perl script fixes 3 different bugs. 
  31. # 1. remove the JCL statements added by some HP printer drivers to the
  32. # beginning of the postscript output. 
  33. # 2. Fix a bug in output from word files with long filenames. A non-printing
  34. # character added to the end of the title comment by word is 
  35. # removed. 
  36. # 3. The VM fix described above.
  37. #
  38. #
  39. # Modified for Perl4 compatibility.
  40. #
  41.  
  42. $PROG = "sambalp";
  43.  
  44. $PSFIX = 1;            # set to 0 if you don't want to run
  45.                 # the "psfix" portion
  46.  
  47. # Untaint the PATH variable
  48. @PATH = split(' ',<<EOF);
  49.     /usr/sbin /usr/bsd /sbin /usr/bin /bin /usr/lib /usr/local/bin
  50. EOF
  51. $ENV{'PATH'} = join(':',@PATH);
  52.  
  53. if ($#ARGV < 3) {
  54.     print STDERR "usage: $PROG printer file user system\n";
  55.     exit;
  56. }
  57.  
  58. $printer = $ARGV[0];
  59. $file    = $ARGV[1];
  60. $user    = $ARGV[2];
  61. $system  = $ARGV[3];
  62.  
  63. open(LPSTAT,"/usr/bin/lpstat -t|") || die("Can't get printer list.\n");
  64. @printers = ();
  65. while (<LPSTAT>) {
  66.     next unless /^printer (\w+)/;
  67.     push(@printers,$1);
  68. }
  69. close LPSTAT;
  70. # Create a hash list
  71. @printers{@printers} = @printers;
  72.     
  73. # Untaint the printer name
  74. if (defined($prtname = $printers{$printer})) {
  75.     $printer = $prtname;
  76. } else {
  77.     die("Unknown printer: \"$printer\"\n");
  78. }
  79.  
  80. if ($> == 0) {        # are we root?
  81.     # yes -- then perform a taint checks and possibly do a suid check
  82.  
  83.     # Untaint the file and system names (pretend to filter them)
  84.     $file   =   $file =~ /^(.*)/ ? $1 : die("Bad file: $file\n");
  85.     $system = $system =~ /^(.*)/ ? $1 : die("Bad system: $system\n");
  86.  
  87.     # Get the valid users
  88.     setpwent;
  89.     %users = ();
  90.     while (@pwe = getpwent()) { 
  91.     $uids{$pwe[0]} = $pwe[2];
  92.     $users{$pwe[2]} = $pwe[0];
  93.     }
  94.     endpwent();
  95.  
  96.     # Check out the user -- if the user is a real user on this system,
  97.     # then become that user so that the  printer header page looks right
  98.     # otherwise, remain as the default user (probably "nobody").
  99.  
  100.     if (defined($uid = $uids{$user})) {
  101.  
  102.     # before we change UID, we must ensure that the file is still
  103.     # readable after the UID change.
  104.     chown($uid, 9, $file);    # make the file owned by the user
  105.  
  106.     # Now, go ahead and become the user
  107.     $name = $users{$uid};
  108.     $> = $uid;        # become the user
  109.     $< = $uid;
  110.     } else {            # do untaint filtering
  111.     $name = $user =~ /^(\w+)/ ? $1 : die("Bad user: $user\n");
  112.     }
  113. } else {            # otherwise, just be me
  114.     $name = $user;        # whomever that is
  115. }
  116.  
  117. $lpcommand = "/usr/bin/lp -c -d$printer -t'$name on $system'";
  118.  
  119. # This code is from the original "psfix" but it has been completely
  120. # rewritten for speed.
  121.  
  122. if ($PSFIX) {            # are we running a "psfix"?
  123.     open(FILE, $file)         || die("Can't read $file: $!\n");
  124.     open(LP, "|$lpcommand -")    || die("Can't open pipe to \"lp\": $!\n");
  125.     select(LP);
  126.     while (<FILE>) {        # 
  127.     $_ =~ s/^\004//;        # strip any ctrl-d's
  128.     if (/^\e%/) {        # get rid of any non-postscript commands
  129.         while (<FILE>) {     # remove text until next %!PS
  130.         s/^\001M//;    # lenmark driver prefixes Ctrl-A M to %!PS
  131.         last if /^%!PS/;
  132.         }
  133.         last if eof(FILE);
  134.     } elsif (/^%%Title:/) {    # fix bug in long titles from MS Word
  135.         s/.\r$/\r/;        # remove trailing character on the title
  136.     } elsif (/^\/VM\?/) {    # remove VM test
  137.         print "/VM? { pop } bind def\r\n";
  138.         while (<FILE>) { last if /def\r/; }
  139.         next;        # don't print
  140.     }
  141.     print;
  142.     }
  143.     close FILE;
  144.     close LP;
  145. } else {            # we're not running psfix?
  146.     system("$lpcommand $file");
  147. }
  148.  
  149. # Remove the file only if it lives in /usr/tmp, /tmp, or /var/tmp.
  150. unlink($file) if $file =~ m=^(/(usr|var))?/tmp=;
  151.